home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / program / vbprnt20.zip / SRC / VBPRNT32.C < prev    next >
C/C++ Source or Header  |  1996-05-31  |  15KB  |  488 lines

  1. /* VBPRNT32.DLL v2.0 Last Updated 05-29-1996 by Robert Simpson
  2.     This version designed for 32-bit Windows apps
  3.  
  4.     NOTES
  5.     This version is designed specifically for 32-bit operation, using the
  6.     expanded DEVMODE structure in Windows 95.
  7.  
  8.     The sample programs, DLL files and all source code have been released
  9.     to the public domain.
  10.  
  11.     This DLL was written and compiled in Borland C++ 4.5
  12. */
  13.  
  14. #include <windows.h>
  15. #include <string.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <math.h>
  19. #include <ctype.h>
  20. #include <dos.h>
  21. #include <ole2.h>
  22.  
  23. #ifdef WIN16
  24. #include <print.h>
  25. #include <olenls.h>
  26. #include <variant.h>
  27. #include <compobj.h>
  28. #include <dispatch.h>
  29. #endif
  30.  
  31. /*  Exported Functions are listed below, here are the proper VB declares:
  32.  
  33. Declare Function VBGetPrinters          Lib "vbprnt32.dll" () As String
  34. Declare Function VBGetDriverFromName  Lib "vbprnt32.dll" (printername As String) As String
  35. Declare Function VBSetDefPrinter          Lib "vbprnt32.dll" (printername As String) As Integer
  36. Declare Function VBGetDefPrinter          Lib "vbprnt32.dll" () As String
  37. Declare Function VBExtDeviceMode          Lib "vbprnt32.dll" (ByVal hWnd As Integer, printername As String, inDev As DEVMODE_TYPE, outDev As DEVMODE_TYPE, ByVal fMode As Integer) As Integer
  38. Declare Function VBDevModeToStr          Lib "vbprnt32.dll" (inDev As DEVMODE_TYPE) As String
  39. Declare Function VBStrToDevMode          Lib "vbprnt32.dll" (dmString As String, outDev As DEVMODE_TYPE) As Integer
  40. Declare Function VBDeviceCapabilities Lib "vbprnt32.dll" (printername As String, ByVal iCap As Integer, lpStr As Any, inDev As DEVMODE_TYPE) As Long
  41. Declare Function VBResetDC            Lib "vbprnt32.dll" (ByVal hDC As Integer, outDev As DEVMODE_TYPE) As Integer
  42.  
  43. ' Here is the VB DEVMODE that should be used in all calls to this DLL requiring a DEVMODE structure:
  44.  
  45. Type DEVMODE_TYPE
  46.   dmDeviceName As String * 32
  47.   dmSpecVersion As Integer
  48.   dmDriverVersion As Integer
  49.   dmSize As Integer
  50.   dmDriverExtra As Integer
  51.   dmFields As Long
  52.   dmOrientation As Integer
  53.   dmPaperSize As Integer
  54.   dmPaperLength As Integer
  55.   dmPaperWidth As Integer
  56.   dmScale As Integer
  57.   dmCopies As Integer
  58.   dmDefaultSource As Integer
  59.   dmPrintQuality As Integer
  60.   dmColor As Integer
  61.   dmDuplex As Integer
  62.   dmYResolution As Integer
  63.   dmTTOption As Integer
  64.   dmCollate As Integer
  65.   dmFormName As String * 32
  66.   dmLogPixels As Integer
  67.   dmBitsPerPel As Long
  68.   dmPelsWidth As Long
  69.   dmPelsHeight As Long
  70.   dmDisplayFlags As Long
  71.   dmDisplayFrequency As Long
  72.   dmPrivate As String
  73. End Type
  74.  
  75. '  The DEVMODE_TYPE structure in VB is essentially a base DEVMODE structure with a dynamic
  76. '  string attached to the end (the C version is directly below, named VBDEVMODE) which
  77. '  holds the printer's private data (if there is any).
  78. */
  79.  
  80. #define PRINTERLIST 2048 // Size of the buffer that holds the available printers
  81.  
  82. #ifdef WIN32
  83. #define CCONV  _stdcall
  84. #else
  85. #define CCONV  FAR PASCAL _export
  86. #endif
  87.  
  88. struct VBDEVMODE      // The C equivilent to the VB DEVMODE_TYPE structure above
  89. {
  90.   DEVMODE dm;        // The size of the DEVMODE structure is larger in Win95 than in Win31
  91.   BSTR *dmPrivate;   // To compensate for size differences, this dmPrivate area holds the extra data
  92. };                   // required by Win95 and by the specific printer driver (if it DOES require anything).
  93.  
  94. // Exported functions
  95. BSTR        CCONV VBGetPrinters(void);
  96. BSTR        CCONV VBGetDriverFromName(BSTR *printername);
  97. short int   CCONV VBSetDefPrinter(BSTR *);
  98. BSTR        CCONV VBGetDefPrinter(void);
  99. short int   CCONV VBExtDeviceMode(HWND,BSTR *,struct VBDEVMODE *,struct VBDEVMODE *,WORD);
  100. BSTR        CCONV VBDevModeToStr(struct VBDEVMODE *);
  101. short int   CCONV VBStrToDevMode(BSTR *,struct VBDEVMODE *);
  102. long        CCONV VBDeviceCapabilities(BSTR *,WORD,LPSTR,struct VBDEVMODE *);
  103. HDC         CCONV VBResetDC(HDC, struct VBDEVMODE *);
  104.  
  105. // Internal functions
  106. short int      GetDriverFromName(BSTR *,LPSTR,LPSTR,LPSTR);
  107. DEVMODE       *GetVBDevMode(struct VBDEVMODE *);
  108. void           SetVBDevMode(DEVMODE *,struct VBDEVMODE *);
  109.  
  110. // 16-Bit Windows only
  111. #ifdef WIN16
  112. typedef int (FAR PASCAL *ExtDeviceMode)(HWND,HANDLE,LPDEVMODE,LPSTR,LPSTR,LPDEVMODE,LPSTR,WORD);
  113. typedef DWORD (FAR PASCAL *DeviceCapabilities)(LPSTR,LPSTR,WORD,LPSTR,LPDEVMODE);
  114. #endif
  115.  
  116. /* This function works similar to the VB Dir$() function.  The first time it is
  117.     called, it retrieves the list of installed printers and returns them one at a
  118.     time to VB.  Each call returns the next installed printer.  A NULL return value
  119.     indicates the end of the list. */
  120. BSTR CCONV VBGetPrinters(void)
  121. {
  122.   static short int prevcall;
  123.   static char printers[PRINTERLIST];
  124.   static char buff[256];
  125.   char printer[64];
  126.   LPSTR driver;
  127.   LPSTR port;
  128.   char output[128];
  129.   LPSTR port2;
  130.  
  131.   if (*printers == 0)
  132.      {
  133.         if (prevcall == 1)
  134.           {
  135.              prevcall = 0;
  136.              return 0;
  137.           }
  138.         prevcall = 1;
  139.         memset(printers,0,PRINTERLIST);
  140.         GetProfileString("devices",NULL,"",printers,PRINTERLIST);
  141.      }
  142.   if (buff[0] != 0)
  143.      {
  144.         port = strchr(buff,',');
  145.         if (port == 0) return 0;
  146.         *port = 0;
  147.         port ++;
  148.         strncpy(printer,buff,(int)(port-buff));
  149.         printer[(int)(port-buff)] = 0;
  150.         driver = strchr(port,',');
  151.         if (driver == 0) return 0;
  152.         driver[0] = 0;
  153.         sprintf(output,"%s on %s",printer,port);
  154.         memmove(buff,driver+1,sizeof buff-(int)(driver-buff));
  155.      }
  156.   else
  157.      {
  158.         strcpy(printer,printers);
  159.         GetProfileString("devices",printer,"",output,sizeof output);
  160.         strtok(output,",");
  161.         port = strtok(NULL,",");
  162.         port2 = strtok(NULL,",");
  163.         while (port2 != 0)
  164.           {
  165.              strcat(buff,printer);
  166.              strcat(buff,",");
  167.              strcat(buff,port2);
  168.              strcat(buff,",");
  169.              port2 = strtok(NULL,",");
  170.           }
  171.         sprintf(output,"%s on %s",printer,port);
  172.         memmove(printers,printers+strlen(printer)+1,PRINTERLIST-(strlen(printer)));
  173.      }
  174. #ifdef WIN32
  175.   return SysAllocStringByteLen(output,strlen(output));
  176. #else
  177.   return SysAllocStringLen((BSTR)output,strlen(output));
  178. #endif
  179.   }
  180.  
  181. /* This function returns the printer driver assigned to the specified printer.
  182.     It's of little use other than reference purposes.  The <printername> VB string
  183.     must follow the format "<printername> on <port>" such as "Epson Stylus COLOR on LPT1:"
  184.     This is the same format that VBGetPrinters() returns the available printers. */
  185. BSTR CCONV VBGetDriverFromName(BSTR *name)
  186. {
  187.   char pname[80];
  188.   char driver[80];
  189.   char port[80];
  190.  
  191.   if (GetDriverFromName(name,pname,driver,port) != 0)
  192. #ifdef WIN32
  193.      return SysAllocStringByteLen(driver,strlen(driver));
  194. #else
  195.      return SysAllocStringLen((BSTR)driver,strlen(driver));
  196. #endif
  197.   return 0;
  198. }
  199.  
  200. /* Internal function to parse the name of a printer and determine its driver and port.
  201.     The caller provides pointers for the name, driver and port that this function
  202.     will fill in */
  203. short int GetDriverFromName(BSTR *name,LPSTR pname,LPSTR pdriver,LPSTR pport)
  204. {
  205.   char printer[128];
  206.   LPSTR port;
  207.   LPSTR driver;
  208.   char iniprinter[128];
  209.   LPSTR found;
  210.  
  211.   strcpy(printer,(LPSTR)*name);
  212.   if (strlen(printer) == 0) return 0;
  213.   found = strstr(printer," on ");
  214.   if (found == 0) return 0;
  215.   *found = 0;
  216.   GetProfileString("devices",printer,"",iniprinter,sizeof iniprinter);
  217.   if (iniprinter[0] == 0) return 0;
  218.   driver = strtok(iniprinter,",");
  219.   port = found+4;
  220.   strcpy(pname,printer);
  221.   strcpy(pdriver,driver);
  222.   strcpy(pport,port);
  223.   return -1;
  224. }
  225.  
  226. /* Sets the default Windows printer. */
  227. short int CCONV VBSetDefPrinter(BSTR *printer)
  228. {
  229.   char newprinter[128];
  230.   char port[32];
  231.   char driver[32];
  232.   char name[32];
  233.  
  234.   if (GetDriverFromName(printer,name,driver,port) == NULL) return 0;
  235.  
  236.   sprintf(newprinter,"%s,%s,%s",name,driver,port);
  237.   WriteProfileString("windows","device",newprinter);
  238.   return -1;
  239. }
  240.  
  241. /* Gets the default Windows printer from the INI file and parses it */
  242. BSTR CCONV VBGetDefPrinter(void)
  243. {
  244.   LPSTR name;
  245.   LPSTR port;
  246.   char inistring[128];
  247.   char final[128];
  248.  
  249.   GetProfileString("windows","device","",inistring,sizeof inistring);
  250.   if (inistring[0] == 0) return 0;
  251.   name = strtok(inistrin